package com.thp.bigdata.myInputFormat;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

/**
 * 定义mapreduce的处理流程
 * @author 汤小萌
 *
 */
public class SmallFilesToSequenceFileConverter extends Configured implements Tool {

	
	static class SequenceFileMapper extends Mapper<NullWritable, BytesWritable, Text, BytesWritable> {
		private Text fileNameKey;
		/**
		 * 由于有三个小文件，所以这个setup方法会走三次
		 * 这个set方法走完之后，就要使用InputFormat去读取文件了
		 * 
		 * 每一次setup方法走之后，就会走WholeFileInputFormat的nextKeyValue()方法
		 * 
		 */
		@Override
		protected void setup(Context context)
				throws IOException, InterruptedException {
			// 是  org.apache.hadoop.mapreduce  包 里面的
			InputSplit split = context.getInputSplit();
			Path path = ((FileSplit)split).getPath();
System.out.println("小文件名： --  " + path.toString());
			fileNameKey = new Text(path.toString());  // 获取小文件的文件名
		}
		
		/**
		 * 一个小文件生成的  key -value 对往同一个文件输出
		 */
		@Override
		protected void map(NullWritable key, BytesWritable value, Context context)
				throws IOException, InterruptedException {
			System.out.println("---------map--------------");
			System.out.println("fileNameKey  :  "  + fileNameKey);
			System.out.println("-----");
			System.out.println("value   :  " + value.toString());
			context.write(fileNameKey, value);
		}
	}
	
	
	
	@Override
	public int run(String[] args) throws Exception {
		Configuration conf = new Configuration();
		// System.setProperty("HADOOP_USER_NAME", "hdfs");
		
		Job job = Job.getInstance(conf,"combine small files to sequencefile");
		job.setJarByClass(SmallFilesToSequenceFileConverter.class);
		
		job.setInputFormatClass(WholeFileInputFormat.class);
		job.setOutputFormatClass(SequenceFileOutputFormat.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(BytesWritable.class);
		
		job.setMapperClass(SequenceFileMapper.class);
		
		FileInputFormat.setInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		return job.waitForCompletion(true) ? 0 : 1;
	}

	public static void main(String[] args) throws Exception {
		args = new String[]{"f:/smallFiles/input","f:/smallFiles/output"};
		int exitCode = ToolRunner.run(new SmallFilesToSequenceFileConverter(), args);
		System.exit(exitCode);
	}

	

}
